package com.xuxueli.applyModules.utils.testcharts;

import org.apache.commons.lang3.time.DateUtils;

import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期处理工具类
 */
public class DateUtil extends DateUtils {

    /**
     * 时间格式(yyyy-MM-dd)
     */
    public final static String DATE_PATTERN = "yyyy-MM-dd";
    /**
     * 时间格式(yyyy-MM-dd HH:mm:ss)
     */
    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * 最大时间
     */
    public static final Date MAX_DATE;

    static {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, 9999);
        calendar.set(Calendar.MONTH, Calendar.DECEMBER);
        calendar.set(Calendar.DAY_OF_MONTH, 31);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        MAX_DATE = calendar.getTime();
    }

    /**
     * 日期格式化 日期格式为：yyyy-MM-dd
     *
     * @param date 日期
     * @return 返回yyyy-MM-dd格式日期
     */
    public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    /**
     * 日期格式化 日期格式为：yyyy-MM-dd
     *
     * @param date    日期
     * @param pattern 格式，如：DateUtils.DATE_TIME_PATTERN
     * @return 返回yyyy-MM-dd格式日期
     */
    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    public static String format(long timeMill, String pattern) {
        Date date = new Date(timeMill);
        return format(date, pattern);
    }


    /**
     * 获取最大日期
     *
     * @return
     */
    public static Date getMaxDate() {
        return MAX_DATE;
    }

    /**
     * 计算两个日期之间相差的天数
     * @param startDate 日期1
     * @param endDate 日期2
     * @return
     */
    public static long dayBetween(Date startDate, Date endDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        LocalDate startLocalDate = LocalDate.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
        calendar.setTime(endDate);
        LocalDate endLocalDate = LocalDate.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
        return ChronoUnit.DAYS.between(startLocalDate, endLocalDate);
    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public static Date getCurrentDate() {
        return new Date();
    }

    public static String getCurrentDateStr() {
        return format(new Date());
    }

    /**
     * 获取前一天日期字符串
     * @return
     */
    public static Date getLastDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }

    /**
     * 对日期的【分钟】进行加/减
     *
     * @param date 日期
     * @param minutes 分钟数，负数为减
     * @return 加/减几分钟后的日期
     */
    public static Date addDateMinutes(Date date, int minutes) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minutes);
        return calendar.getTime();
    }

    public static Time parseTime(final String str, final String... parsePatterns) throws ParseException {
        Date date = parseDate(str, parsePatterns);
        return new Time(date.getTime());
    }

    /**
     * 将Time类型的时间转换为指定日期的时间
     * @param time
     * @param date 为空时，默认为当前日期
     * @return
     */
    public static Date convertTimeToDate(Time time, Date date) {
        if(time == null) {
            throw new RuntimeException("time不能为空");
        }
        if(date == null) {
            date = getCurrentDate();
        }

        Calendar specialCalendar = Calendar.getInstance();
        specialCalendar.setTime(date);

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time.getTime());
        calendar.set(Calendar.YEAR, specialCalendar.get(Calendar.YEAR));
        calendar.set(Calendar.MONTH, specialCalendar.get(Calendar.MONTH));
        calendar.set(Calendar.DAY_OF_MONTH, specialCalendar.get(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.MILLISECOND, 0);

        return calendar.getTime();
    }

    /**
     * 比较两个日期大小，比较位精确到分
     * @param date
     * @param otherDate
     * @return -1：date < otherDate；1：date > otherDate；0：date == otherDate
     */
    public static int compareDate(Date date, Date otherDate) {
        return compareDate(date, otherDate, Calendar.MINUTE);
    }

    /**
     * 比较两个日期大小，
     * @param date
     * @param otherDate
     * @param exactValue
     * @return -1：date < otherDate；1：date > otherDate；0：date == otherDate
     */
    public static int compareDate(Date date, Date otherDate, int exactValue) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Calendar otherCalendar = Calendar.getInstance();
        otherCalendar.setTime(otherDate);
        switch (exactValue) {
            case Calendar.YEAR:
                calendar.set(Calendar.MONTH, Calendar.JANUARY);
                otherCalendar.set(Calendar.MONTH, Calendar.JANUARY);
            case Calendar.MONTH:
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                otherCalendar.set(Calendar.DAY_OF_MONTH, 1);
            case Calendar.DAY_OF_MONTH:
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                otherCalendar.set(Calendar.HOUR_OF_DAY, 0);
            case Calendar.HOUR_OF_DAY:
                calendar.set(Calendar.MINUTE, 0);
                otherCalendar.set(Calendar.MINUTE, 0);
            case Calendar.MINUTE:
                calendar.set(Calendar.SECOND, 0);
                otherCalendar.set(Calendar.SECOND, 0);
            case Calendar.SECOND:
                calendar.set(Calendar.MILLISECOND, 0);
                otherCalendar.set(Calendar.MILLISECOND, 0);
            default:
                break;
        }

        long millisecond = calendar.getTimeInMillis();
        long otherMillisecond = otherCalendar.getTimeInMillis();

        if(millisecond < otherMillisecond) {
            return -1;
        }
        if(millisecond > otherMillisecond) {
            return 1;
        }
        return 0;
    }

    /**
     * 判断是否unix时间戳格式(就判断是不是纯数字)
     */
    public static boolean isUnixTimestamp(String possiblyStr) {
        return possiblyStr.matches("^\\\\d+$");
    }

    /**
     * 判断是否unix时间戳格式(就判断是不是纯数字)
     */
    public static boolean isDateStrWith(String possiblyStr) {
        return possiblyStr.matches("^\\\\d+$");
    }

    /**
     * Unix时间戳转Date
     */
    public static Date parseUnixDate(long unixTimestamp) {
        return new Date(unixTimestamp);
    }

    /**
     * Unix时间戳转Date
     */
    public static Date parseUnixDate(String unixTimestamp) {
        return isUnixTimestamp(unixTimestamp) ? parseUnixDate(Long.valueOf(unixTimestamp)) : null;
    }

    /**
     * Unix时间戳日期格式化
     */
    public static String formatUnixTimestamp(long unixTimestamp, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(parseUnixDate(unixTimestamp));
    }

    /**
     * Unix时间戳日期格式化
     */
    public static String formatUnixTimestamp(String unixTimestamp, String pattern) {
        Date date = parseUnixDate(unixTimestamp);
        if (null == date) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

//    /**
//     * 格式猜测
//     */
//    public static Date computeAndFormatDate(String dateStr) {
//        Date d = null;
//        if (DateUtils.isUnixTimestamp(dateStr)) {
//            d = DateUtils.parseUnixDate(dateStr);
//        } else {
//            String patternByDateStr = DatePattern.getPatternByDateStr(dateStr);
//            if(StringUtils.isBlank(patternByDateStr)){
//                throw new RuntimeException("日期格式有误");
//            }
//            try {
//                d = DateUtils.parseDate(dateStr,patternByDateStr);
//            } catch (ParseException e) {
//                throw new RuntimeException("日期格式有误");
//            }
//        }
//        return d;
//    }

    /**
     * 格式猜测
     */
    public static String getFormatToString(String format,Date now) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(now);
    }

    /**
     * 格式猜测
     */
    public static Date getFormatToDate(String format,String value) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(value);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 格式猜测
     */
    public static Date getFormatDate(String format,Date now) {
        String patternByDateStr = DateUtil.getFormatToString(format,now);
        Date date = DateUtil.getFormatToDate(patternByDateStr,format);
        return date;
    }

}
